package com.module.ble.widget

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.common.base.app.extras.yes
import com.common.base.utils.ViewUtils
import com.common.base.utils.ViewUtils.dp2px
import com.common.base.utils.ViewUtils.sp2px
import com.module.ble.R
import com.module.ble.data.bean.CusChartData

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2028/08/11
 *
 * 描述：历史数据定制折线图表控件
 * 支持自定义Y轴阶段配置、X轴时间标签、触摸交互等功能
 * 修订历史：
 *
 */
class HdBrokenLineChart @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 接口定义
    interface OnBarTouchListener {
        fun onBarTouched(index: Int, minValue: Float, maxValue: Float, timeLabel: String,exValue: Float,)
        fun onTouchReleased()
    }

    // 画笔
    private val linePaint = Paint(Paint.ANTI_ALIAS_FLAG) // 折线画笔
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 文字画笔
    private val yAxisTextPaint = Paint(Paint.ANTI_ALIAS_FLAG) // Y轴标记文字画笔
    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 背景画笔
    private val touchLinePaint = Paint(Paint.ANTI_ALIAS_FLAG) // 触摸实线画笔
    private val paintPolyShadow = Paint().apply {
        style = Paint.Style.FILL
        isAntiAlias = true
    } // 折线阴影画笔

    // 数据
    private var dataValues = mutableListOf<CusChartData>()

    // X轴时间标签
    private var customTimeLabels = mutableMapOf<Int, String>()

    // Y轴配置
    private var yAxisStages = floatArrayOf(0f, 50f, 100f) // 默认三个阶段

    // 触摸相关
    private var touchListener: OnBarTouchListener? = null
    private var isTouching = false
    private var touchedBarIndex = -1
    private var touchLineX = 0f

    // 颜色配置
    private var activeBarColor = ViewUtils.getColor(R.color.c_5282ff) // 蓝色
    private var textColor = ViewUtils.getColor(R.color.c_7f7f7f)
    private var gridLineColor = ViewUtils.getColor(R.color.color_d9d9d9)
    private var chartBackgroundColor = ViewUtils.getColor(R.color.color_FAFAFA) // 柱状图背景色
    private var touchLineColor = ViewUtils.getColor(R.color.black) // 触摸实线颜色
    private var backgroundShadowColor = ViewUtils.getColor(R.color.c_409966ff)// 折线阴影颜色

    // 基准值属性
    private val basicLinePaint = Paint(Paint.ANTI_ALIAS_FLAG) // 基准线画笔
    private var mBasic: Float = 0f // 基准值
    private var basicBarColor = ViewUtils.getColor(R.color.c_5282ff) // 基准线颜色

    // 尺寸配置
    private var barSpacing = dp2px(25f)
    private var textSize = sp2px(12f)
    private var chartPaddingTop = dp2px(5f)
    private var chartPaddingBottom = dp2px(30f)

    // Y轴色块尺寸
    private var yAxisTextSize = sp2px(10f) // Y轴标记文字大小
    private var yAxisTextMargin = dp2px(5f) // 标记文字距离右边的间距
    // Y轴mark文字拼接内容
    private var yAxisTextEx: String? = ""

    // 柱子圆角控制
    private var enableBarTopRounding = true // 控制柱子顶部圆角
    private var enableBarBottomRounding = true // 控制柱子底部圆角

    // X轴中间线控制
    private var enableXAxisSolidLine = false // 控制X轴中间线绘制方式
    // 触摸总开关
    private var isTouchEnabled = true // 触摸总开关，默认开启
    // Y轴中间虚线显示
    private var showYMiddleLine = true//是否绘制Y轴中间虚线
    // 阴影绘制控制开关
    private var isShadowEnabled = true

    init {
        // 从XML属性中读取配置
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CandlestickChart)
        activeBarColor = typedArray.getColor(
            R.styleable.CandlestickChart_signs_candlestick_barDefaultColor,
            activeBarColor
        )
        yAxisTextEx = typedArray.getString(R.styleable.CandlestickChart_signs_candlestick_y_exText)
        backgroundShadowColor = typedArray.getColor(
            R.styleable.CandlestickChart_signs_candlestick_backgroundShadowColor,
            activeBarColor
        )
        typedArray.recycle()

        // 初始化文字画笔
        textPaint.color = textColor
        textPaint.textSize = textSize
        textPaint.textAlign = Paint.Align.CENTER

        // 初始化Y轴文字画笔
        yAxisTextPaint.color = textColor
        yAxisTextPaint.textSize = yAxisTextSize
        yAxisTextPaint.textAlign = Paint.Align.LEFT

        // 初始化背景画笔
        backgroundPaint.color = chartBackgroundColor
        backgroundPaint.style = Paint.Style.FILL

        // 初始化触摸线画笔
        touchLinePaint.color = touchLineColor
        touchLinePaint.strokeWidth = dp2px(1f)
        touchLinePaint.style = Paint.Style.STROKE

        // 初始化基准线画笔
        basicBarColor = activeBarColor
        basicLinePaint.color = basicBarColor
        basicLinePaint.strokeWidth = dp2px(1f)
        basicLinePaint.pathEffect = DashPathEffect(floatArrayOf(dp2px(2f), dp2px(2f)), 0f)
        basicLinePaint.style = Paint.Style.STROKE

        // 初始化折线画笔
        linePaint.color = activeBarColor
        linePaint.strokeWidth = dp2px(1f)
        linePaint.style = Paint.Style.STROKE
        linePaint.strokeCap = Paint.Cap.ROUND
        linePaint.strokeJoin = Paint.Join.ROUND

        // 初始化默认数据
        initializeDefaultData()
    }

    /**
     * 初始化默认数据
     */

    private fun initializeDefaultData() {
        // 如果没有数据，创建一些默认数据用于预览
        if (dataValues.isEmpty()) {
            // 可以根据需要调整默认数据数量
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)

        // 确保控件有最小尺寸
        val minWidth = dp2px(200f).toInt()
        val minHeight = dp2px(150f).toInt()

        setMeasuredDimension(
            width.coerceAtLeast(minWidth),
            height.coerceAtLeast(minHeight)
        )
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 如果没有数据，不绘制任何内容
        if (dataValues.isEmpty()) {
            return
        }

        // 计算图表高度（减去上下边距）
        val chartHeight = height - chartPaddingTop - chartPaddingBottom

        // 按顺序绘制各个组件
        drawChartBackground(canvas, chartHeight) // 绘制背景
        drawYAxisGrid(canvas, chartHeight) // 绘制Y轴网格线
//        drawXAxisGrid(canvas, chartHeight) // 绘制X轴网格线
        drawBasicLine(canvas, chartHeight) // 绘制基准线
        drawLine(canvas, chartHeight) // 绘制折线图
        drawTouchLine(canvas, chartHeight) // 绘制触摸线
        drawTimeLabels(canvas, chartHeight) // 绘制X轴标签
        drawYAxisStageIndicators(canvas, chartHeight) // 绘制Y轴标记

        // 如果正在触摸，可以在这里添加额外的绘制逻辑
        if (isTouching) {
            // 例如：绘制触摸提示信息
        }
    }

    /**
     * 绘制图表背景
     */
    private fun drawChartBackground(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 绘制图表背景矩形
        val backgroundRect = RectF(
            0f,
            chartPaddingTop,
            yAxisBarX,
            chartPaddingTop + chartHeight
        )
        canvas.drawRect(backgroundRect, backgroundPaint)
    }

    /**
     * 绘制Y轴网格线
     */
    private fun drawYAxisGrid(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 柱状图起始位置（左对齐）
        val barsStartX = 0f

        // 网格线右边界：Y轴标记文字的右侧
        val gridLineEndX = yAxisBarX + yAxisTextMargin + maxTextWidth

        // 创建虚线画笔
        val dashedLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = gridLineColor
            strokeWidth = dp2px(1f)
            pathEffect = DashPathEffect(floatArrayOf(dp2px(2f), dp2px(3f)), 0f)
        }

        // 创建加粗实线画笔（用于顶部和底部）
        val boldLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = gridLineColor
            strokeWidth = dp2px(1f) // 加粗线条
        }

        // 获取Y轴范围
        val minValue = yAxisStages.first()
        val maxValue = yAxisStages.last()
        val valueRange = maxValue - minValue

        // 绘制Y轴网格线
        for (i in yAxisStages.indices) {
            val stage = yAxisStages[i]
            val normalizedStage = (stage - minValue) / valueRange

            when (i) {
                0 -> {
                    // 底部网格线（最小值）- 绘制在柱状图下方
                    val bottomY = chartPaddingTop + chartHeight + dp2px(1f) // 在图表底部下方1dp处
                    canvas.drawLine(
                        barsStartX,
                        bottomY,
                        gridLineEndX,
                        bottomY,
                        boldLinePaint
                    )
                }

                yAxisStages.size - 1 -> {
                    // 顶部网格线（最大值）- 加粗实线
                    val y = chartPaddingTop + chartHeight * (1 - normalizedStage) - dp2px(1f)
                    canvas.drawLine(
                        barsStartX,
                        y,
                        gridLineEndX,
                        y,
                        boldLinePaint
                    )
                }

                else -> {
                    showYMiddleLine.yes {
                        // 中间的网格线 - 虚线
                        val y = chartPaddingTop + chartHeight * (1 - normalizedStage)
                        canvas.drawLine(
                            barsStartX,
                            y,
                            yAxisBarX,
                            y,
                            dashedLinePaint
                        )
                    }
                }
            }
        }
    }

    /**
     * 绘制X轴网格线
     */
    private fun drawXAxisGrid(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 计算总的柱状图宽度
        val totalBarWidth = dataValues.size * barWidth + totalSpacingWidth

        // 根据开关选择绘制方式
        if (enableXAxisSolidLine) {
            // 绘制实线画笔
            val solidLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                color = gridLineColor
                strokeWidth = dp2px(1f)
                style = Paint.Style.STROKE
            }

            // 绘制X轴网格线（根据自定义时间标签位置）
            for ((barIndex, _) in customTimeLabels) {
                val gridLineX = if (barIndex == 0) {
                    // 第一个标签与第一个柱子的左边对齐
                    startX
                } else if (barIndex >= dataValues.size - 1) {
                    // 最后一个标签位于最右侧
                    startX + totalBarWidth
                } else {
                    // 其他标签位于对应柱子的中心
                    startX + barIndex * (barWidth + barSpacing) + barWidth / 2
                }

                // 计算底部Y轴线的位置
                val bottomYAxisLine = chartPaddingTop + chartHeight + dp2px(1f)

                // 绘制从底部Y轴线开始向上8px高度的垂直实线
                canvas.drawLine(
                    gridLineX,
                    bottomYAxisLine, // 从底部Y轴线开始
                    gridLineX,
                    bottomYAxisLine - dp2px(8f), // 向上8px高度
                    solidLinePaint
                )
            }
        } else {
            // 创建虚线画笔用于X轴网格线
            val xAxisGridPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
                color = gridLineColor
                strokeWidth = dp2px(1f)
                pathEffect = DashPathEffect(floatArrayOf(dp2px(2f), dp2px(3f)), 0f)
            }

            // 绘制X轴网格线（除首尾的时间标签位置）
            for ((barIndex, _) in customTimeLabels) {
                // 跳过首尾位置
                if (barIndex == 0 || barIndex >= dataValues.size - 1) continue

                // 计算网格线的X位置（对应柱子的中心）
                val gridLineX = startX + barIndex * (barWidth + barSpacing) + barWidth / 2

                // 绘制从图表顶部到底部的垂直虚线
                canvas.drawLine(
                    gridLineX,
                    chartPaddingTop, // 图表顶部
                    gridLineX,
                    chartPaddingTop + chartHeight, // 图表底部
                    xAxisGridPaint
                )
            }
        }
    }

    /**
     * 绘制折线图
     */
    private fun drawLine(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        // 获取Y轴范围
        val yAxisMinValue = yAxisStages.first()
        val yAxisMaxValue = yAxisStages.last()
        val yAxisValueRange = yAxisMaxValue - yAxisMinValue

        // 创建折线路径
        val linePath = Path()
        var hasFirstPoint = false

        // 创建阴影路径（仅当开关开启时）
        val shadowPath = Path()
        var shadowStarted = false

        // 绘制折线和阴影
        for (i in dataValues.indices) {
            val dataValue = dataValues[i].mValue

            // 限制数据值在Y轴有效范围内
            val clampedValue = dataValue.coerceIn(yAxisMinValue, yAxisMaxValue)

            // 将数据值映射到图表坐标
            val normalizedValue =
                if (yAxisValueRange > 0) (clampedValue - yAxisMinValue) / yAxisValueRange else 0f

            // 计算点的坐标
            val pointX = startX + i * (barWidth + barSpacing) + barWidth / 2
            val pointY = chartPaddingTop + chartHeight * (1 - normalizedValue)

            if (!hasFirstPoint) {
                // 移动到第一个点
                linePath.moveTo(pointX, pointY)
                hasFirstPoint = true

                // 添加到阴影路径（只有当值大于最小值且阴影开关开启时才添加到阴影）
                if (isShadowEnabled && clampedValue > yAxisMinValue) {
                    shadowPath.moveTo(pointX, chartPaddingTop + chartHeight)
                    shadowPath.lineTo(pointX, pointY)
                    shadowStarted = true
                }
            } else {
                // 连线到下一个点
                linePath.lineTo(pointX, pointY)

                // 添加到阴影路径（只有当值大于最小值且阴影开关开启时才添加到阴影）
                if (isShadowEnabled && clampedValue > yAxisMinValue) {
                    if (!shadowStarted) {
                        shadowPath.moveTo(pointX, chartPaddingTop + chartHeight)
                        shadowPath.lineTo(pointX, pointY)
                        shadowStarted = true
                    } else {
                        shadowPath.lineTo(pointX, pointY)
                    }
                } else if (isShadowEnabled && shadowStarted && clampedValue == yAxisMinValue) {
                    // 当前值为最小值，结束阴影
                    val prevIndex = i - 1
                    val prevPointX = startX + prevIndex * (barWidth + barSpacing) + barWidth / 2
                    shadowPath.lineTo(prevPointX, chartPaddingTop + chartHeight)
                    shadowPath.close()
                    shadowStarted = false
                }
            }
        }

        // 完成阴影路径
        if (isShadowEnabled && shadowStarted) {
            val lastIndex = dataValues.size - 1
            val lastX = startX + lastIndex * (barWidth + barSpacing) + barWidth / 2
            shadowPath.lineTo(lastX, chartPaddingTop + chartHeight)
            shadowPath.close()
        }

        // 绘制阴影（仅当开关开启时）
        if (isShadowEnabled && !shadowPath.isEmpty) {
            val shadowShader = LinearGradient(
                0f, chartPaddingTop,
                0f, chartPaddingTop + chartHeight,
                backgroundShadowColor,
                0x00000000,
                Shader.TileMode.CLAMP
            )
            paintPolyShadow.shader = shadowShader
            canvas.drawPath(shadowPath, paintPolyShadow)
        }

        // 绘制折线
        canvas.drawPath(linePath, linePaint)

        // 绘制数据点（可选）
        val pointPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        pointPaint.color = linePaint.color
        pointPaint.style = Paint.Style.FILL
        val pointRadius = dp2px(2.5f)

        for (i in dataValues.indices) {
            val dataValue = dataValues[i].mValue
            val clampedValue = dataValue.coerceIn(yAxisMinValue, yAxisMaxValue)
            val normalizedValue =
                if (yAxisValueRange > 0) (clampedValue - yAxisMinValue) / yAxisValueRange else 0f

            val pointX = startX + i * (barWidth + barSpacing) + barWidth / 2
            val pointY = chartPaddingTop + chartHeight * (1 - normalizedValue)

            canvas.drawCircle(pointX, pointY, pointRadius, pointPaint)
        }
    }

    /**
     * 绘制基准线
     * 根据mBasic值在Y轴对应位置绘制虚线
     */
    private fun drawBasicLine(canvas: Canvas, chartHeight: Float) {
        if (mBasic <= 0f) return // 如果基准值无效，不绘制

        // 计算Y轴文字区域的位置
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 获取Y轴范围
        val yAxisMinValue = yAxisStages.first()
        val yAxisMaxValue = yAxisStages.last()
        val yAxisValueRange = yAxisMaxValue - yAxisMinValue

        // 检查基准值是否在Y轴范围内
        if (mBasic < yAxisMinValue || mBasic > yAxisMaxValue) return

        // 计算基准线的Y位置
        val normalizedBasic = (mBasic - yAxisMinValue) / yAxisValueRange
        val basicLineY = chartPaddingTop + chartHeight * (1 - normalizedBasic)

        // 绘制基准线（从图表左边界到Y轴文字区域右边界）
        val lineStartX = 0f
        val lineEndX = yAxisBarX

        canvas.drawLine(
            lineStartX,
            basicLineY,
            lineEndX,
            basicLineY,
            basicLinePaint
        )
    }

    /**
     * 绘制触摸线
     */
    private fun drawTouchLine(canvas: Canvas, chartHeight: Float) {
        if (touchedBarIndex >= 0 && touchedBarIndex < dataValues.size) {
            // 绘制垂直触摸线
            canvas.drawLine(
                touchLineX,
                chartPaddingTop,
                touchLineX,
                chartPaddingTop + chartHeight,
                touchLinePaint
            )
        }
    }

    /**
     * 绘制X轴标签
     */
    private fun drawTimeLabels(canvas: Canvas, chartHeight: Float) {
        // 计算Y轴文字区域的位置（去除色块宽度）
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        // 计算所有barSpacing的总宽度
        val totalSpacingWidth = (dataValues.size - 1) * barSpacing

        // 计算每条柱子的宽度
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size

        // 柱状图起始位置（左对齐）
        val startX = 0f

        val labelY = chartPaddingTop + chartHeight + dp2px(20f)

        // 绘制自定义时间标签
        for ((barIndex, labelText) in customTimeLabels) {
            // 所有标签都位于对应柱子的中心
            val labelX = startX + barIndex * (barWidth + barSpacing) + barWidth / 2

            // 所有标签都使用居中对齐
            canvas.drawText(labelText, labelX, labelY, textPaint)
        }
    }

    /**
     * 绘制右侧Y轴标记文字（去除色块）
     */
    private fun drawYAxisStageIndicators(canvas: Canvas, chartHeight: Float) {
        // 动态计算最大文字宽度
        val maxTextWidth = calculateMaxYAxisTextWidth()

        // 计算总的指示器宽度（去除色块宽度）
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth

        // Y轴文字的X位置：从控件最右边往左计算
        val yAxisTextX = width - totalIndicatorWidth

        // 获取Y轴范围
        val minValue = yAxisStages.first()
        val maxValue = yAxisStages.last()
        val valueRange = maxValue - minValue

        // 绘制所有阶段的标记文字（包括第一个起始值）
        for (i in yAxisStages.indices) {
            val stage = yAxisStages[i]

            // 计算网格线的Y位置
            val normalizedStage = (stage - minValue) / valueRange
            val gridLineY = when (i) {
                0 -> {
                    // 底部网格线位置（在图表底部下方1dp处）
                    chartPaddingTop + chartHeight + dp2px(1f)
                }

                yAxisStages.size - 1 -> {
                    // 顶部网格线位置（在图表顶部上方1dp处）
                    chartPaddingTop + chartHeight * (1 - normalizedStage) - dp2px(1f)
                }

                else -> {
                    // 中间网格线位置
                    chartPaddingTop + chartHeight * (1 - normalizedStage)
                }
            }

            // 计算文字的Y位置
            val textMetrics = yAxisTextPaint.fontMetrics
            val textHeight = textMetrics.descent - textMetrics.ascent

            val textY = when (i) {
                0 -> {
                    // 底部标记文字：显示在底部粗实线的上方
                    gridLineY - textMetrics.descent - dp2px(2f)
                }

                yAxisStages.size - 1 -> {
                    // 顶部标记文字：显示在顶部粗实线的下方
                    gridLineY - textMetrics.ascent + dp2px(2f)
                }

                else -> {
                    // 中间标记文字：与网格线垂直居中对齐
                    gridLineY - textMetrics.ascent - textHeight / 2
                }
            }

            val textX = yAxisTextX + yAxisTextMargin

            // 使用阶段值的toString()作为标签，去掉小数点后的0
            val label = if (stage % 1.0f == 0.0f) {
                stage.toInt().toString()
            } else {
                stage.toString()
            }
            canvas.drawText(
                if (yAxisTextEx.isNullOrEmpty()) label else "$label$yAxisTextEx",
                textX,
                textY,
                yAxisTextPaint
            )
        }
    }

    /**
     * 计算Y轴文字的最大宽度
     */
    private fun calculateMaxYAxisTextWidth(): Float {
        var maxWidth = 0f
        for (stage in yAxisStages) {
            val valueText = if (stage == stage.toInt().toFloat()) {
                "${stage.toInt()}${yAxisTextEx ?: ""}"
            } else {
                "${String.format("%.1f", stage)}${yAxisTextEx ?: ""}"
            }
            val textWidth = yAxisTextPaint.measureText(valueText)
            if (textWidth > maxWidth) {
                maxWidth = textWidth
            }
        }
        return maxWidth
    }

    /**
     * 查找父级ViewPager2
     */
    private fun findViewPager2(): androidx.viewpager2.widget.ViewPager2? {
        var parent = parent
        while (parent != null) {
            if (parent is androidx.viewpager2.widget.ViewPager2) {
                return parent
            }
            parent = parent.parent
        }
        return null
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        // 如果触摸开关关闭，直接透传到父视图
        if (!isTouchEnabled) {
            return super.onTouchEvent(event)
        }

        if (dataValues.isNullOrEmpty()) return true//无数据是直接透传触摸

        val viewPager2 = findViewPager2()

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (isTouchInChartArea(event.x, event.y)) {
                    // 直接禁用ViewPager2的用户输入
                    viewPager2?.isUserInputEnabled = false
                    parent?.requestDisallowInterceptTouchEvent(true)
                    handleTouch(event.x)
                    return true
                }
            }

            MotionEvent.ACTION_MOVE -> {
                if (isTouching && isTouchInChartArea(event.x, event.y)) {
                    handleTouch(event.x)
                    return true
                }
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (isTouching) {
                    // 恢复ViewPager2的用户输入
                    viewPager2?.isUserInputEnabled = true
                    parent?.requestDisallowInterceptTouchEvent(false)
                    handleTouchRelease()
                    return true
                }
            }
        }
        return super.onTouchEvent(event)
    }

    /**
     * 判断触摸点是否在图表区域内
     */
    private fun isTouchInChartArea(x: Float, y: Float): Boolean {
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        return x >= 0 && x <= yAxisBarX &&
                y >= chartPaddingTop && y <= height - chartPaddingBottom
    }

    /**
     * 处理触摸事件
     */
    private fun handleTouch(touchX: Float) {
        val maxTextWidth = calculateMaxYAxisTextWidth()
        val totalIndicatorWidth = yAxisTextMargin + maxTextWidth
        val yAxisBarX = width - totalIndicatorWidth

        val totalSpacingWidth = (dataValues.size - 1) * barSpacing
        val barWidth = (yAxisBarX - totalSpacingWidth) / dataValues.size
        val startX = 0f

        // 计算触摸的柱子索引
        var touchedIndex = -1
        for (i in dataValues.indices) {
            val left = startX + i * (barWidth + barSpacing)
            val right = left + barWidth

            if (touchX >= left && touchX <= right) {
                touchedIndex = i
                break
            }
        }

        if (touchedIndex >= 0 && touchedIndex < dataValues.size) {
            isTouching = true
            touchedBarIndex = touchedIndex
            touchLineX = startX + touchedIndex * (barWidth + barSpacing) + barWidth / 2

            val data = dataValues[touchedIndex]
            val timeLabel = getTimeLabel(touchedIndex)

            touchListener?.onBarTouched(touchedIndex, data.minValue, data.mValue, timeLabel, 0f)

            invalidate()
        }
    }

    /**
     * 处理触摸释放
     */
    private fun handleTouchRelease() {
        isTouching = false
        touchedBarIndex = -1
        touchListener?.onTouchReleased()
        invalidate()
    }

    /**
     * 根据索引获取时间标签
     */
    private fun getTimeLabel(index: Int): String {
        // 优先使用自定义时间标签
        return customTimeLabels[index] ?: run {
            // 如果没有自定义标签，使用原有逻辑生成
            val hour = index / 2 // 每小时2个数据点
            val minute = if (index % 2 == 0) "00" else "30"
            String.format("%02d:%s", hour, minute)
        }
    }

    // 公共方法

    /**
     * 设置Y轴阶段配置
     */
    fun setYAxisStages(stages: FloatArray) {
        yAxisStages = stages
        invalidate()
    }

    /**
     * 设置数据（支持动态数量）
     */
    fun setData(data: List<CusChartData>) {
        dataValues.clear()
        dataValues.addAll(data)
        invalidate()
    }

    /**
     * 设置颜色
     */
    fun setActiveBarColor(activeColor: Int) {
        activeBarColor = activeColor
        invalidate()
    }

    /**
     * 设置折线颜色
     */
    fun setLineColor(color: Int) {
        linePaint.color = color
        invalidate()
    }

    /**
     * 设置折线宽度
     */
    fun setLineWidth(widthDp: Float) {
        linePaint.strokeWidth = dp2px(widthDp)
        invalidate()
    }

    /**
     * 设置触摸监听器
     */
    fun setOnBarTouchListener(listener: OnBarTouchListener?) {
        touchListener = listener
    }

    /**
     * 设置柱子顶部圆角
     * @param enable true: 启用顶部圆角, false: 禁用顶部圆角
     */
    fun setBarTopRounding(enable: Boolean) {
        enableBarTopRounding = enable
        invalidate()
    }

    /**
     * 设置柱子底部圆角
     * @param enable true: 启用底部圆角, false: 禁用底部圆角
     */
    fun setBarBottomRounding(enable: Boolean) {
        enableBarBottomRounding = enable
        invalidate()
    }

    /**
     * 设置柱子圆角（同时控制顶部和底部）
     * @param enableTop 是否启用顶部圆角
     * @param enableBottom 是否启用底部圆角
     */
    fun setBarRounding(enableTop: Boolean, enableBottom: Boolean) {
        enableBarTopRounding = enableTop
        enableBarBottomRounding = enableBottom
        invalidate()
    }

    /**
     * 设置X轴中间线绘制方式
     * @param enable true: 绘制8px高度的实线, false: 绘制点虚线
     */
    fun setXAxisSolidLineEnabled(enable: Boolean) {
        enableXAxisSolidLine = enable
        invalidate()
    }

    /**
     * 获取X轴中间线绘制方式
     * @return true: 实线模式, false: 虚线模式
     */
    fun isXAxisSolidLineEnabled(): Boolean {
        return enableXAxisSolidLine
    }

    /**
     * 设置触摸开关
     * @param enabled true为启用触摸，false为禁用触摸
     */
    fun setTouchEnabled(enabled: Boolean) {
        if (isTouchEnabled != enabled) {
            isTouchEnabled = enabled
            // 如果禁用触摸时正在触摸，需要重置触摸状态
            if (!enabled && isTouching) {
                isTouching = false
                touchedBarIndex = -1
                touchListener?.onTouchReleased()
                invalidate()
            }
        }
    }

    /**
     * 获取触摸开关状态
     */
    fun isTouchEnabled(): Boolean = isTouchEnabled

    /**
     * 设置自定义X轴时间标签
     * @param timeLabels Map<Int, String> key为柱子索引（从0开始），value为显示的时间标签内容
     */
    fun setCustomTimeLabels(timeLabels: Map<Int, String>) {
        customTimeLabels.clear()
        customTimeLabels.putAll(timeLabels)
        invalidate()
    }

    /**
     * 添加单个时间标签
     * @param barIndex 柱子索引（从0开始）
     * @param label 时间标签内容
     */
    fun addTimeLabel(barIndex: Int, label: String) {
        customTimeLabels[barIndex] = label
        invalidate()
    }

    /**
     * 清除所有自定义时间标签
     */
    fun clearCustomTimeLabels() {
        customTimeLabels.clear()
        invalidate()
    }

    /**
     * 获取当前自定义时间标签
     */
    fun getCustomTimeLabels(): Map<Int, String> {
        return customTimeLabels.toMap()
    }

    /**
     * 设置基准值
     * @param basic 基准值
     */
    fun setBasicValue(basic: Float) {
        mBasic = basic
        invalidate()
    }

    /**
     * 获取基准值
     * @return 当前基准值
     */
    fun getBasicValue(): Float {
        return mBasic
    }

    /**
     * 设置是否绘制Y轴中间虚线
     * @param isShow
     */
    fun showYMiddleLine(isShow: Boolean) {
        showYMiddleLine = isShow
        invalidate()
    }

    /**
     * 设置柱间距
     * @param basic
     */
    fun setBarSpacing(value: Float) {
        barSpacing = dp2px(value)
        invalidate()
    }

}